package com.xltt.vehicleControl.activity;

import android.net.NetworkUtils;
import android.os.Handler;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;

import com.xltt.vehicleControl.BuildConfig;
import com.xltt.vehicleControl.R;
import com.xltt.vehicleControl.base.BaseFragment;
import com.xltt.vehicleControl.base.BaseMvpActivity;
import com.xltt.vehicleControl.base.MyApplication;
import com.xltt.vehicleControl.bean.BaseData;
import com.xltt.vehicleControl.bean.BaseResult;
import com.xltt.vehicleControl.bean.Capability;
import com.xltt.vehicleControl.bean.ControlPushEvent;
import com.xltt.vehicleControl.bean.PushConfig;
import com.xltt.vehicleControl.bean.RemoteControlRequest;
import com.xltt.vehicleControl.bean.RemoteControlResponse;
import com.xltt.vehicleControl.bean.ReposFactory;
import com.xltt.vehicleControl.bean.ServiceResult;
import com.xltt.vehicleControl.bean.TcVehicleProfile;
import com.xltt.vehicleControl.bean.TcVehicleProfileResponse;
import com.xltt.vehicleControl.bean.TscVehicleCapabilityResponse;
import com.xltt.vehicleControl.bean.UpdateSession;
import com.xltt.vehicleControl.bean.UserResponse;
import com.xltt.vehicleControl.bean.VehicleStatus;
import com.xltt.vehicleControl.bean.VehicleStatusResponse;
import com.xltt.vehicleControl.contants.Constants;
import com.xltt.vehicleControl.contants.ResponseCode;
import com.xltt.vehicleControl.contract.IVehicleControlContract;
import com.xltt.vehicleControl.fragment.VehicleBindTipsFragment;
import com.xltt.vehicleControl.fragment.VehicleFunctionFragment;
import com.xltt.vehicleControl.fragment.VehicleInfoFragment;
import com.xltt.vehicleControl.fragment.VehicleSettingsFragment;
import com.xltt.vehicleControl.presenter.VehicleControlPresenter;
import com.xltt.vehicleControl.revice.AliPushMessageReceiver;
import com.xltt.vehicleControl.util.CProgressDialogUtils;
import com.xltt.vehicleControl.util.HProgressDialogUtils;
import com.xltt.vehicleControl.util.Logger;
import com.xltt.vehicleControl.util.NetWorkUtils;
import com.xltt.vehicleControl.util.SharedPreferencesUtils;
import com.xltt.vehicleControl.util.ToastUtil;
import com.xltt.vehicleControl.view.LoadingDialog;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.greenrobot.eventbus.EventBus;

import butterknife.BindView;

public class LauncherActivity extends BaseMvpActivity<LauncherActivity, VehicleControlPresenter> implements IVehicleControlContract.IVehicleControlView  {
    @BindView(R.id.vp_home_pager)
    ViewPager mViewPager;
    @BindView(R.id.dot_layout)
    LinearLayout mDotLayout;
    @BindView(R.id.loading_layout)
    LinearLayout mLoadingLayout;


    private ImageView[] mDotViews;
    private List<BaseFragment> mFragmentList = new ArrayList<>();//所有fragment

    private List<VehicleCallBack> mVehicleObservers = new ArrayList<>();//所有被观察对象
    public interface VehicleCallBack{
        int COMPLETE = 1;
        int WAIT = 2;
        void onRefreshInfo(VehicleStatus vehicleStatus,String plateNo);
        void onRemoteControl(int result);
        void onFunctionList(List<Capability> capabilityList);
    }
    public void registerObserver(VehicleCallBack vehicleCallBack){
        mVehicleObservers.add(vehicleCallBack);
    }
    public void removeAllObserver() {
        for(int i = 0;i < mVehicleObservers.size(); i++) {
            VehicleCallBack observer = mVehicleObservers.get(i);
            mVehicleObservers.remove(observer);
        }
//        int i = mVehicleObservers.indexOf(refreshVehicleCallBack);
//        if(i >= 0) {
//            mVehicleObservers.remove(i);
//        }
    }

    /**
     * 车辆功能有哪些（X50与X70功能不一样，需要区分）
     * @param capabilityList
     */
    private void notifyFunctionListObservers(List<Capability> capabilityList){
        for(int i = 0;i < mVehicleObservers.size(); i++) {
            VehicleCallBack observer = mVehicleObservers.get(i);
            observer.onFunctionList(capabilityList);
        }
    }

    /**
     * 触发命令后返回的结果，通知刷新UI
     * @param result
     */
    private void notifyRemoteControlObservers(int result){
        for(int i = 0;i < mVehicleObservers.size(); i++) {
            VehicleCallBack observer = mVehicleObservers.get(i);
            observer.onRemoteControl(result);
        }
    }

    /**
     * 展示车辆当前状态信息
     * @param vehicleStatus
     * @param plateNo
     */
    private void notifyRefreshObservers(VehicleStatus vehicleStatus,String plateNo){
        for(int i = 0;i < mVehicleObservers.size(); i++) {
            VehicleCallBack observer = mVehicleObservers.get(i);
            observer.onRefreshInfo(vehicleStatus,plateNo);
        }
    }

    private List<Capability> mCapabilityList;
    public List<Capability> getCapabilityList(){
        return this.mCapabilityList;
    }

    @Override
    protected int getLayoutId() {
        return R.layout.activity_launcher;
    }

    @Override
    protected void initViews() {
        //请求权限
        //initActivity();
        super.requestPermission(new String[]{
                android.Manifest.permission.ACCESS_FINE_LOCATION,//位置
                android.Manifest.permission.ACCESS_COARSE_LOCATION,//位置
                android.Manifest.permission.READ_CONTACTS,//联系人
                android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
                android.Manifest.permission.READ_EXTERNAL_STORAGE,
        }, "请求权限", new GrantedResult() {
            @Override
            public void onResult(boolean granted) {
                if (granted) {
                    initActivity();
                } else {
                    finish();
                }
            }
        });
    }

    private void initActivity(){
        //0.判断是否第一次登录（不能根据账号密码是否为空判断，因为第一次绑定会传账号密码过来）
        int firstBoot = 0;
        if(Constants.DEBUG){
            firstBoot = Integer.valueOf(SharedPreferencesUtils.getParam(LauncherActivity.this,Constants.FIRST_BOOT,0).toString());
        }else{
            firstBoot = Settings.Global.getInt(LauncherActivity.this.getContentResolver(), Constants.FIRST_BOOT,0);
        }

        Logger.d("first boot ,value = " + firstBoot);
        if(firstBoot == 0){
            doLogin(0);
            return;
        }
        //1.判断是否点击退出过登录，如果是直接回到登录界面 2021/4/19 + {
//                    String userName = getLoginUser();
//                    String password = getLoginPassword();
//                    if(TextUtils.isEmpty(userName) || TextUtils.isEmpty(password)){
//                        doLogin(LoginActivity.LOGOUT_CODE);
//                        //ToastUtil.show(LauncherActivity.this,getString(R.string.Login_expired));
//                        return;
//                    }
        //2021/4/19 + }
        //2.初始化fragment
        initFragment();
        //3.判断登录后的token是否有效
        String userId = LoginInvalidation();
        if(TextUtils.isEmpty(userId)){
            ToastUtil.show(LauncherActivity.this,getString(R.string.Login_expired));
            doLogin(0);
            return;
        }
        //4.获取绑定默认车辆
        initBindVehicleList(userId);
        //5.注册通知
        EventBus.getDefault().register(LauncherActivity.this);
    }

    /**
     * 获取绑定车辆列表
     */
    public void initBindVehicleList(String userId){
        getPresenter().getVehicleList(userId,"all");
    }

    /**
     * 控车功能
     * @param request
     */
    public void controlVehicleCommand(RemoteControlRequest request){
        if(!NetWorkUtils.isAvailable(this)){
            ToastUtil.show(this,getString(R.string.please_connect_network_tip));
            return;
        }
        TcVehicleProfile info = ReposFactory.getInstance().getTcVehicleProfile();
        if(info == null){
            ToastUtil.show(this,"controll vehicle commad error");
            doLogin(0);
            return;
        }
        //CProgressDialogUtils.showProgressDialog(this);
        mLoadingLayout.setVisibility(View.VISIBLE);
        getPresenter().remoteControl(info.getVin(),request);
    }

    /**
     * 初始化车控警告状态
     * @param vin
     */
    private void updateSession(String vin, UpdateSession updateSession){
        getPresenter().update(vin,updateSession);
        Logger.d("开始初始化车辆警告状态 ");
    }

    /**
     * 获取默认车辆能力集
     * @param vin
     * @param vehicleType
     */
    private void getVehicleCapability(String vin,int vehicleType){
        Logger.d("getVehicleCapability() vin = " + vin + ",vehicleType = " + vehicleType);
        getPresenter().getVehicleCapability(vin,1000,1,vehicleType,null,null);
    }

    /**
     * 接收阿里推送数据状态
     * @param pushEvent
     */
    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void processAliPushMessage(ControlPushEvent pushEvent){
        if(pushEvent == null){
            return;
        }
        int operationResult = pushEvent.getResult();
        if(operationResult == AliPushMessageReceiver.REFRESH_UI){
            mHandler.removeCallbacks(mRunnable);
            notifyRemoteControlObservers(VehicleCallBack.COMPLETE);
        }else if(operationResult == AliPushMessageReceiver.REFRESH_DATA){
            initVehicleStatus();
            notifyRemoteControlObservers(VehicleCallBack.COMPLETE);
        }else if(operationResult == ServiceResult.RESULT_OTHER_DEVICE){
            ToastUtil.show(this,this.getString(R.string.other_user_push_msg));
            doLogin(0);
        }
    }

    /**
     * 获取车子状态
     */
    public void initVehicleStatus(){
        TcVehicleProfile info = ReposFactory.getInstance().getTcVehicleProfile();
        if(info == null){
            Logger.e("init vehicle status error ,case：vin is null");
            ToastUtil.show(LauncherActivity.this,getString(R.string.get_bind_vechile_vin_error));
            doLogin(0);
            return;
        }
        String vim = info.getVin();
//        String userId = ReposFactory.getInstance().getUserResponse().getUserId();
        String userId = SharedPreferencesUtils.getParam(this,LoginActivity.USERID,"").toString();
        Logger.d("initVehicleStatus() vim = " + vim + " ,userId = " + userId);
        getPresenter().getVehicleStatus(vim,userId,"false","more");
    }

    /**
     * 初始化fragment
     */
    private void initFragment(){
        mFragmentList.clear();
        //fragment page
        mFragmentList.add(new VehicleInfoFragment());
        mFragmentList.add(new VehicleFunctionFragment());
        mFragmentList.add(new VehicleSettingsFragment());
        //dot layout
        createDot(mFragmentList.size());
        //viewpager data
        mViewPager.setAdapter(mFragmentStatePagerAdapter);
        mViewPager.setOnPageChangeListener(mOnPageChangeListener);
        mViewPager.setOffscreenPageLimit(2);
        //mViewPager.setCurrentItem(0, false);
    }



    /**
     * 根据绑定默认车辆刷新Fragment
     * @param bindVehicleList
     */
    private void updateFragment(List<TcVehicleProfile> bindVehicleList){
        //1.判断是否有绑定车辆
        if(bindVehicleList == null || bindVehicleList.size() == 0){
            Logger.e("bind vechile list is null");
//            mFragmentList.clear();
//            mFragmentList.add(new VehicleBindTipsFragment());
//            mViewPager.setAdapter(mFragmentStatePagerAdapter);
            ToastUtil.show(LauncherActivity.this,getString(R.string.phone_bind_vehicle_tip));
            doLogin(0);
            return;
        }
        //2.设置默认绑定车辆信息到内存
        TcVehicleProfile mDefaultVehicle = null;
        for (TcVehicleProfile defaultOne : bindVehicleList){
            if(defaultOne.isDefaultVehicle()){
                mDefaultVehicle = defaultOne;
                //1.2 记录数据保存到内存，用来控车命令使用
                ReposFactory.getInstance().setTcVehicleProfile(mDefaultVehicle);
                Logger.d("get default bind vehicle info = " + mDefaultVehicle.toString());
                //1.3 获取车辆能力集
                getVehicleCapability(mDefaultVehicle.getVin(),mDefaultVehicle.getVehicleType());
                //1.4初始化车子警告阿里推送数据
                UserResponse mUserResponse = ReposFactory.getInstance().getUserResponse();
                String accessToken = mUserResponse.getAccessToken();
                Logger.d("get default accessToken = " + accessToken);
                if(TextUtils.isEmpty(accessToken)){
                    return;
                }
                if(mUserResponse != null){
                    String vin = mDefaultVehicle.getVin();
                    updateSession(vin,new UpdateSession(vin,accessToken,"en_US"));
                }
                break;
            }
        }
        //3.获取默认车子首页状态信息
        initVehicleStatus();
    }


    private ViewPager.OnPageChangeListener mOnPageChangeListener = new ViewPager.OnPageChangeListener(){
        @Override
        public void onPageSelected(int position) {
            // TODO Auto-generated method stub
            Logger.i("position = " + position);
            for (int i = 0; i < mDotViews.length; i++) {
                if (position == i) {
                    mDotViews[i].setSelected(true);
                } else {
                    mDotViews[i].setSelected(false);
                }
            }
        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onPageScrollStateChanged(int arg0) {
            // TODO Auto-generated method stub

        }
    };

    private FragmentStatePagerAdapter mFragmentStatePagerAdapter = new FragmentStatePagerAdapter(getSupportFragmentManager()){
        @Override
        public Fragment getItem(int position) {
            return mFragmentList.get(position);
        }

        @Override
        public int getCount() {
            return mFragmentList.size();
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            super.destroyItem(container, position, object);
        }
    };

    /**
     * 生成底部dot点
     * @param dotCount
     */
    private void createDot(int dotCount) {
        LinearLayout.LayoutParams mParams = new LinearLayout.LayoutParams(
                15,
                15);
        mParams.setMargins(5, 0, 5, 0);// 设置小圆点左右之间的间隔
        mDotLayout.removeAllViews();//清空所有子节点
        mDotViews = new ImageView[dotCount];
        for (int i = 0; i < dotCount; i++) {
            ImageView dotViews = new ImageView(this);
            dotViews.setLayoutParams(mParams);
            dotViews.setImageResource(R.drawable.dot_selector);
            if (i == 0) {
                dotViews.setSelected(true);// 默认启动时，选中第一个小圆点
            } else {
                dotViews.setSelected(false);
            }
            mDotViews[i] = dotViews;
            mDotLayout.addView(dotViews);// 添加到布局里面显示
        }
    }

    @Override
    public void updateResult(BaseResult<BaseData> data) {
        int code = data.getCode();
        Logger.d("初始化车辆警告状态成功 ，code = " + code);
    }

    @Override
    public void deviceConfigResult(PushConfig pushConfig) {
        Logger.d("MyApplication，start bind ali push ,deviceConfigResult()");
        PushConfig.DataDTO config = pushConfig.getData();
        ((MyApplication)getApplication()).addAlias(config.getAliasName());
    }

    @Override
    protected VehicleControlPresenter createPresenter() {
        return VehicleControlPresenter.getInstance();
    }

    @Override
    public void getVehicleListResult(BaseResult<TcVehicleProfileResponse> retrofitEntity) {
        //1.验证获取绑定车辆服务器返回错误信息
        int resultCode = retrofitEntity.getCode();
        if(tokenInvalidation(resultCode)){
            ToastUtil.show(this,getString(R.string.Login_expired));
            doLogin(0);
            return;
        }
        //2.判断账号是否绑定默认车辆，更改Fragment状态
        TcVehicleProfileResponse user = retrofitEntity.getData();
        List<TcVehicleProfile> bindVehicleList = user.getList();
        updateFragment(bindVehicleList);
        //3.初始化推送消息
        MyApplication application = ((MyApplication)getApplication());
        boolean bindAliPush = application.bindAliPush();
        if(bindAliPush){
            Logger.d("MyApplication , ali push is bind ");
            return;
        }
        initDeviceConfig();
    }

    /**
     * 服务器与阿里云推送进行绑定
     */
    public void initDeviceConfig(){
        String clientId = SharedPreferencesUtils.getParam(LauncherActivity.this,LoginActivity.CLIENT_ID,"").toString();
        Logger.d("MyApplication red client_id = " + clientId);
        getPresenter().deviceConfig(clientId, Constants.APPID,Constants.GAP,Constants.APPTYPE,Constants.ALIPUSHID,Constants.DEVICECLASS,Constants.MODELCODE,Constants.PUSHTYPE);
    }

    @Override
    public void remoteControlResult(BaseResult<RemoteControlResponse> user) {
        //0.需要加载提示
        //CProgressDialogUtils.cancelProgressDialog();
        mLoadingLayout.setVisibility(View.INVISIBLE);
        //1、判断是否过期token
        int code = user.getCode();
        if(tokenInvalidation(code)){
            ToastUtil.show(this,getString(R.string.Login_expired));
            doLogin(0);
            return;
        }
        //2、判断是否操作成功
        int icon = R.mipmap.success_icon;
        String message = getString(R.string.success);
        if(code == ResponseCode.CODE_1000){
            icon = R.mipmap.success_icon;
            message = getString(R.string.cmd_send_success);
        }else if(code == ResponseCode.CODE_8070){
            icon = R.mipmap.faild_icon;
            message = getString(R.string.last_request_no_completed);
        }else{
            icon = R.mipmap.faild_icon;
            message = getString(R.string.cmd_send_faild);
        }
        this.showDialog(icon,message);
        //3.记录当前操作成功指令，等待30秒如果没有收到阿里推送的结果就提示用户操作失败
        if(code == ResponseCode.CODE_1000){
            notifyRemoteControlObservers(VehicleCallBack.WAIT);
            mHandler.postDelayed(mRunnable,1000 * 60);
        }
    }
    private Handler mHandler = new Handler();
    private Runnable mRunnable = new Runnable(){
        @Override
        public void run() {
            // TODO Auto-generated method stub
            ToastUtil.show(LauncherActivity.this,getString(R.string.cmd_overtime_tip));
            notifyRemoteControlObservers(VehicleCallBack.COMPLETE);
        }
    };




    @Override
    public void getVehicleStatusResult(BaseResult<VehicleStatusResponse> user) {
        //1.验证服务器返回错误信息
        int resultCode = user.getCode();
        if(tokenInvalidation(resultCode)){
            ToastUtil.show(this,getString(R.string.Login_expired));
            doLogin(0);
            return;
        }
        //2.验证绑定车子数据非空判断
        VehicleStatusResponse vehicleStatusResponse = user.getData();
        int code = vehicleStatusResponse.getCode();
        if(vehicleStatusResponse == null || code == ResponseCode.CODE_8007){
            doLogin(0);
            ToastUtil.show(this,getString(R.string.phone_bind_vehicle_tip));
            return;
        }
        VehicleStatus vehicleStatus = vehicleStatusResponse.getVehicleStatus();
        if(vehicleStatus == null){
            doLogin(0);
            ToastUtil.show(this,getString(R.string.server_bind_vehicle_status_error_tip));
            return;
        }
        //3.通知VehicleInfofragment刷新UI
//        if(mRefreshVehicleCallBack != null){
        TcVehicleProfile mTcVehicleProfile = ReposFactory.getInstance().getTcVehicleProfile();
        String plateNo = getString(R.string.unknown);
        if(mTcVehicleProfile != null){
            plateNo = mTcVehicleProfile.getPlateNo();
        }
        notifyRefreshObservers(vehicleStatus,plateNo);
//            mRefreshVehicleCallBack.onVehicleInfo(vehicleStatus,plateNo);
//        }
    }

    @Override
    public void getVehicleCapabilityResult(BaseResult<TscVehicleCapabilityResponse> data) {
        //1.验证服务器返回错误信息
        int resultCode = data.getCode();
        if(tokenInvalidation(resultCode)){
            ToastUtil.show(this,getString(R.string.Login_expired));
            doLogin(0);
            return;
        }
        this.mCapabilityList = data.getData().getList();
        notifyFunctionListObservers(mCapabilityList);
        for (int i = 0;i < mCapabilityList.size();i++){
            Capability mCapability = mCapabilityList.get(i);
            Logger.d("获取车辆拥有能力集 = " + mCapability.getFunctionId());
        }
    }

    /**
     * 登出
     */
    public void logout(){
        getPresenter().logout();
    }

    @Override
    public void logoutResult(BaseResult<BaseData> user) {
        if(user.getCode() == ResponseCode.CODE_1000 || tokenInvalidation(user.getCode())){
            doLogin(LoginActivity.LOGOUT_CODE);
            return;
        }
        ToastUtil.show(this,getString(R.string.logout_error));
    }

    private LoadingDialog mLoadDilaog;
    @Override
    public void showProgressDialog() {
        mLoadDilaog = new LoadingDialog.Builder(this)
                .create();
        mLoadDilaog.show();
    }

    @Override
    public void hideProgressDialog() {
        if(mLoadDilaog != null){
            mLoadDilaog.dismiss();
        }
    }

    @Override
    public void onError(String result) {
        //ToastUtil.show(this,result);
        mLoadingLayout.setVisibility(View.INVISIBLE);
        //CProgressDialogUtils.cancelProgressDialog();
    }

    @Override
    public void onBackPressed() {
        Logger.d("onBackPressed");
        super.onBackPressed();
    }

    @Override
    protected void onDestroy() {
        //((MyApplication)getApplication()).cancelCloudChannel(this);
        if(EventBus.getDefault().isRegistered(this)){
            EventBus.getDefault().unregister(this);
        }
        removeAllObserver();
        ((MyApplication)getApplication()).removeAlias();
        super.onDestroy();
    }

}
